/*
    This file is part of Advanced Strategic Command; http://www.asc-hq.de
    Copyright (C) 1994-1999  Martin Bickel  and  Marc Schellenberger

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; see the file COPYING. If not, write to the 
    Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
    Boston, MA  02111-1307  USA
*/

#include <stdlib.h>
#include "../basegfx.h"
#include "../loadpcx.h"
#include "../newfont.h"
#include "../misc.h"
#include "../buildingtype.h"
#include "../vehicletype.h"
#include "../graphicset.h"
#include "../graphicselector.h"
#include "../sgstream.h"
#include "../strtmesg.h"
#include "../textfileparser.h"
#include "../itemrepository.h"

#ifdef WIN32
#undef main
#endif

int background = 255;

struct tbipictparam {
   int textnum;
   struct {
     char text[40];
     int color;
   } entry[20];
} bipict[4000];

// #include "../objxlat.cpp"

// including the command line parser, which is generated by genparse
#include "../clparser/gfx2pcx.cpp"

int main(int argc, char *argv[] )
{
   Cmdline cl ( argc, argv );

   if ( cl.v() ) {
      cout << argv[0] << " " << getVersionString() << endl;
      exit(0);
   }

  int index = cl.legend();
  int wide =  cl.wide();
  int verbosity = cl.r();
  int scale = 0;
  if ( cl.doublen() )
     scale = 1;
  else
    if ( cl.doublei() )
       scale = 2;

  int usage = !cl.nousage();
  int id = cl.id();
  keeporiginalpalette = cl.orgpal();
  int i;

   initFileIO( cl.c().c_str() );
   opencontainer ( "*.con" );

   loadpalette();
   loadbi3graphics();

   loadAllData( false );
   loadUnitSets();

//   readBI3translationTable();

   memset ( bipict, 0, sizeof ( 0 ) );
   try {
      if ( usage ) {
         ASCString itemlistfile = getSearchPath(0) + "itemname.txt";
         FILE* fp = fopen (itemlistfile.c_str(), filewritemodetext );
         printf(" Printing graphics usage to text file %s \n\n", itemlistfile.c_str() );


         {
         /*
            for ( int i = 0; i < getterraintranslatenum(); i++ ) {
               const int* p = getterraintranslate(i);
               int n = p[0];
               int t = bipict[n].textnum++;
               sprintf ( bipict [ n ].entry[ t ] .text, "=> %d", p[1] );
               bipict [ n ].entry[ t ].color = 1;
            }
            */
         }

         {
            printf("\nLoading terrain:\n");
            for ( int trr = 0; trr < terraintypenum; trr++ ) {

               pterraintype bdt = getterraintype_forpos(trr);
               fprintf(fp, "\n%s ; id %d ; pictures ", bdt->filename.c_str(), bdt->id );

               for ( int i = 0; i< cwettertypennum; i++ )
                  if ( bdt->weather[i] )
                        if ( bdt->weather[i]->pict )
                           if ( bdt->weather[i]->bi_pict >= 0 ) {
                              int n = bdt->weather[i]->bi_pict;
                              int t = bipict[n].textnum++;
                              if ( (i == 0)  ||  (bdt->weather[0]->bi_pict < 0) ) {
                                 sprintf ( bipict [ n ].entry[ t ] .text, "%s (%d)", bdt->filename.c_str(), bdt->id );
                                 bipict [ n ].entry[ t ].color = 1;
                              } else {
                                 sprintf ( bipict [ n ].entry[ t ] .text, "-> %d ; w=%d", bdt->weather[0]->bi_pict,i );
                                 bipict [ n ].entry[ t ].color = 1;
                              }
                              fprintf( fp, "%d ", n );
                           }
            }
         }

         {
         /*
            for ( int i = 0; i < getobjectcontainertranslatenum(); i++ ) {
               const int* p = getobjectcontainertranslate(i);
               for ( int j = 1; j < 5; j++ )
                  if ( p[j] >= 0 ) {
                     int n = p[0];
                     int t = bipict[n].textnum++;
                     sprintf ( bipict [ n ].entry[ t ] .text, "=> %d", p[j] );
                     bipict [ n ].entry[ t ].color = 2;
                  }
            }
            */
         }
         {
            printf("\nLoading objects:\n");
            for ( int ob = 0; ob < objecttypenum; ob++ ) {
               Object*type obj = getobjecttype_forpos( ob );
               fprintf(fp, "\n%s ; id %d ; pictures ", obj->filename.c_str(), obj->id );

               for ( int w = 0; w < cwettertypennum; w++ )
                  if ( obj->weather.test(w)  )
                     for ( int i = 0; i< obj->weatherPicture[w].images.size() ; i++ )
                         if ( obj->weatherPicture[w].bi3pic[i] >= 0 ) {
                            int n = obj->weatherPicture[w].bi3pic[i];
                            int t = bipict[n].textnum;
                            bipict[n].textnum += 2;

                            sprintf ( bipict [ n ].entry[ t ] .text, "%s (%d)", obj->filename.c_str(), obj->id );
                            sprintf ( bipict [ n ].entry[ t+1 ] .text, "    #%d ", i );
                            if ( obj->weatherPicture[w].flip[i] & 1 )
                               strcat ( bipict [ n ].entry[ t+1 ] .text, "H" );
                            if ( obj->weatherPicture[w].flip[i] & 2 )
                               strcat ( bipict [ n ].entry[ t+1 ] .text, "V" );

                            fprintf( fp, "%d ", n );

                            bipict [ n ].entry[ t ].color = 2;
                            bipict [ n ].entry[ t+1 ].color = 2;
                         }

            }
         }

         {
            printf("\nLoading buildings:\n");
            for ( int bl = 0; bl < buildingtypenum; bl++ ) {

               BuildingType* bld = getbuildingtype_forpos ( bl );
               fprintf(fp, "\n%s ; id %d ; pictures ", bld->filename.c_str(), bld->id );

               for ( int i = 0; i< cwettertypennum ; i++ )
                  for ( int j = 0; j < maxbuildingpicnum; j++ )
                     for ( int k = 0; k < 4; k++ )
                        for ( int l = 0; l < 6; l++ )
                           if ( bld->w_picture[i][j][k][l] )
                              if ( bld->bi_picture[i][j][k][l] >= 0 ) {
                                 int n = bld->bi_picture[i][j][k][l];
                                 int t = bipict[n].textnum;
                                 bipict[n].textnum += 2;

                                 sprintf ( bipict [ n ].entry[ t ] .text, "%s (%d)", bld->filename.c_str(), bld->id );
                                 sprintf ( bipict [ n ].entry[ t+1 ] .text, "    W=%d #%d X=%d Y=%d", i, j, k, l );

                                 fprintf( fp, "%d ", n );

                                 bipict [ n ].entry[ t ].color = 3;
                                 bipict [ n ].entry[ t+1 ].color = 3;
                              }
            }
         }

         {
            printf("\nLoading vehicles:\n");
            for ( int ve = 0; ve < vehicletypenum; ve++ ) {

               VehicleType* tnk = getvehicletype_forpos( ve );
               fprintf(fp, "\n%s ; id %d ; pictures ", tnk->filename.c_str(), tnk->id );

               if ( tnk->bipicture > 0 ) {
                  int n = tnk->bipicture;
                  int t = bipict[n].textnum;
                  bipict[n].textnum += 1;

                  sprintf ( bipict [ n ].entry[ t ] .text, "%s (%d)", tnk->filename.c_str(), tnk->id );

                  fprintf( fp, "%d ", n );

                  bipict [ n ].entry[ t ].color = 4;
               }
            }

         }
         fclose(fp);
      } else
         loadbi3graphics();



      char* name = "monogui.fnt";
      pfont fnt;
      {
         tnfilestream stream ( name, tnstream::reading );
         fnt = loadfont  ( &stream );
      }
      if ( !fnt ) {
         printf("error loading file %s \n", name );
         return 1;
      }
   
      int ys;
      int colnum;
      if ( wide ) {
         ys = 1600 * (usage+1);
         colnum = 10;
      } else {
         ys = 800 * (usage+1);
         colnum = 5;
      }

      printf("\nallocating buffer \n" ) ;
      fflush ( stdout );

      tvirtualdisplay vdp ( ys, 30000 / ( wide + 1 ) * (!!scale+1), 255 );

      int colxl[] = {0, black, blue, green, red };

      int x0 = 30;
      int xd = ( agmp->resolutionx - 2 * x0 ) / colnum ;


      int y0 = 10;
      int yd;
      if ( scale )
         yd = fieldsizey + 5;
      else
         yd = fieldsizey/2 + 5;

      activefontsettings.font = fnt;
      activefontsettings.color = black;
      activefontsettings.background = 255;
      activefontsettings.length = xd;
      activefontsettings.justify = lefttext;
      activefontsettings.height = 0;


      int yp = y0;
      int lastlinenum = 0;

      if ( wide )
         line ( agmp->resolutionx / 2 - 3, 0, agmp->resolutionx / 2 - 3, agmp->resolutiony -1, black );

      printf("Generating image: \n" ) ;
      fflush ( stdout );
      activateGraphicSet ( id );
      for ( i = 0; i < getActiveGraphicSet()->getNum(); i++ ) {
         void* v;
         if ( scale == 0 )
            loadbi3pict ( i, &v );
         else
            loadbi3pict_double ( i, &v, scale-1 );

         if ( !(i % colnum) ) {
            if ( i ) {
              if ( yd > (activefontsettings.font->height + 2 )* lastlinenum )
                 yp += yd;
              else
                 yp += (activefontsettings.font->height + 2 ) * (lastlinenum + 1);
            }
            lastlinenum = 0;
            activefontsettings.color = black;
            showtext2 ( strrr ( i ), 1, yp + ( yd - 5 - activefontsettings.font->height) / 2 );

            if ( verbosity )
               printf ( "line %d\n", i / colnum );
            else
               printf(".");
            fflush ( stdout );
         }

         if ( v ) {
            putimage ( x0 + (i % colnum) * xd, yp, v );
            if ( usage )
               for ( int j = 0; j < bipict[i].textnum; j++ ) {
                  activefontsettings.color = colxl[bipict[i].entry[j].color];
                  showtext2 ( bipict[i].entry[j].text, x0 + (i % colnum) * xd + (scale ? fieldsizex : fieldsizex/2) + 5 , yp + j * (activefontsettings.font->height + 2 ));

                  if ( lastlinenum < j+1 )
                     lastlinenum = j+1;
               }
   
   
            delete v;
   
         }
      }
   
      printf ( "\nwriting pcx \n" );
      char* outputfilename = "bi_graph.pcx";
      writepcx ( outputfilename, 0, 0, agmp->resolutionx-1, yp + yd + (activefontsettings.font->height + 2 ) * (lastlinenum + 1), pal );
      printf ( "%s written\n", outputfilename );
   
      if ( index ) {
         tnfilestream strm ( "bi_index.raw", tnstream::reading );
         int w;
         void* p;
         strm.readrlepict ( &p, false, &w );
         putimage ( 0, 0, p );
         char* outputfilename2 = "INDEX.PCX";
         writepcx ( outputfilename2, 0, 0, 639, 479, pal );
         printf ( "\nIndex file %s written\n", outputfilename2 );
      }

   } /* endtry */
   catch ( tfileerror err ) {
      printf("\nfatal error accessing file %s \n", err.getFileName().c_str() );
      return 1;
   } /* endcatch */
   catch ( ASCexception ) {
      printf("\na fatal exception occured\n" );
      return 2;
   } /* endcatch */

   if ( keeporiginalpalette )
      printf("\n\nPlease apply the correct palette yourself !\n\n");

   return 0;

}
